package com.zhuo.common.service.tencent;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.zhuo.common.config.StorageProperties;
import com.zhuo.common.domain.storage.UploadOptions;
import com.zhuo.common.domain.storage.UploadResult;
import com.zhuo.common.exception.StorageException;
import com.zhuo.common.helper.UploadResultHelper;
import com.zhuo.common.service.DefaultStorageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.channels.FileChannel;

public class TencentCosService extends DefaultStorageService {

    private static final Logger log = LoggerFactory.getLogger(TencentCosService.class);

    private final TencentCosProperties properties;

    public TencentCosService(StorageProperties storageProperties) {
        super(storageProperties);
        this.properties = storageProperties.getCos();
    }

    /**
     * 单例cosClient
     */
    private static volatile COSClient cosClient;

    /**
     * 获取单例 COSClient，懒加载线程安全
     */
    private COSClient getCosClient() {
        // 双检 创建单例cosClient
        if (cosClient == null) {
            synchronized (TencentCosService.class) {
                if (cosClient == null) {
                    cosClient = CosUtil.createCOSClient(properties.getSecretId(), properties.getSecretKey(), properties.getRegion());
                }
            }
        }
        return cosClient;
    }

    /**
     * cos核心上传方法
     */
    @Override
    protected UploadResult doUpload(InputStream inputStream, UploadOptions options) {
        // 从 options 获取生成好的 key
        String key = options.getKey();
        try {
            ObjectMetadata metadata = new ObjectMetadata();
            // 如果是可获取长度的输入流，设置 ContentLength
            if (inputStream instanceof FileInputStream) {
                FileInputStream fis = (FileInputStream) inputStream;
                FileChannel channel = fis.getChannel();
                metadata.setContentLength(channel.size());
            } else if (options.getFileSize() != null) {
                metadata.setContentLength(options.getFileSize());
            }

            // 设置 content-type
            String contentType = detectContentType(options.getFileName());
            metadata.setContentType(contentType);

            PutObjectRequest request = new PutObjectRequest(properties.getBucketName(), key, inputStream, metadata);
            getCosClient().putObject(request);

            return UploadResultHelper.buildSuccessUpload(key, getUrl(key), options.getFileName(), properties.getBucketName());
        } catch (Exception e) {
            throw new StorageException("上传失败：" + e.getMessage());
        }
    }

    // ========== 其他功能 ==========
    @Override
    public boolean delete(String key) {
        try {
            getCosClient().deleteObject(properties.getBucketName(), key);
            return true;
        } catch (Exception e) {
            log.warn("cos delete object fail ... the reason:{}", e.getMessage());
            throw new StorageException("删除失败：" + e.getMessage());
        }
    }

    @Override
    public String getUrl(String key) {
        return String.format("https://%s.cos.%s.myqcloud.com/%s", properties.getBucketName(), properties.getRegion(), key);
    }

    @Override
    public boolean doesObjectExist(String key) {
        try {
            return getCosClient().doesObjectExist(properties.getBucketName(), key);
        } catch (Exception e) {
            return false;
        }
    }
}
